﻿using System.Collections.Concurrent;
using NLog;
using StackExchange.Redis;

namespace Redis.StackExchange
{
    public class MyRedisClient
    {
        private static readonly Logger Logger = LogManager.GetCurrentClassLogger();

        #region 单例

        private static readonly ConcurrentDictionary<string, ConnectionMultiplexer> DicRedisClient =
            new ConcurrentDictionary<string, ConnectionMultiplexer>();

        private static readonly object LockHelper = new object();

        private MyRedisClient()
        {
        }

        public static ConnectionMultiplexer GetInstance(string host, int port, string password = "")
        {
            if (DicRedisClient.ContainsKey($"{host}:{port}"))
            {
                var client = DicRedisClient[$"{host}:{port}"];
                return client;
            }
            lock (LockHelper)
            {
                if (!DicRedisClient.ContainsKey($"{host}:{port}"))
                {
                    var client = DicRedisClient.GetOrAdd($"{host}:{port}",
                        ConnectionMultiplexer.Connect($"{host}:{port},password={password},allowAdmin=true"));
                    
                    client.ConnectionFailed += (s, e) =>
                    {
                        Logger.Fatal(
                            $"ConnectionFailed|{host}|{port}|{e.EndPoint}|{e.FailureType}|{e.Exception?.Message}");
                    };
                    client.ConnectionRestored += (s, e) =>
                    {
                        Logger.Warn(
                            $"ConnectionRestored|{host}|{port}|{e.EndPoint}|{e.FailureType}|{e.Exception?.Message}");
                    };
                    client.ErrorMessage += (s, e) =>
                    {
                        Logger.Fatal($"ErrorMessage|{host}|{port}|{e.EndPoint}|{e.Message}");
                    };
                    client.ConfigurationChanged += (s, e) =>
                    {
                        Logger.Warn($"ConfigurationChanged|{host}|{port}|{e.EndPoint}");
                    };
                    client.HashSlotMoved += (s, e) =>
                    {
                        Logger.Warn(
                            $"HashSlotMoved|{host}|{port}|HashSlotMoved: NewEndPoint {e.NewEndPoint}, OldEndPoint {e.OldEndPoint}");
                    };
                    client.InternalError += (s, e) =>
                    {
                        Logger.Fatal($"InternalError|{host}|{port}|{e.EndPoint}|{e.Origin}|{e.Exception?.Message}");
                    };
                    client.ConfigurationChangedBroadcast += (s, e) =>
                    {
                        Logger.Warn($"ConfigurationChangedBroadcast|{host}|{port}|{e.EndPoint}");
                    };
                    return client;
                }
                else
                {
                    var client = DicRedisClient[$"{host}:{port}"];
                    return client;
                }
            }
        }

        #endregion

    }
}
